package com.dji.sample.manage.controller;

import com.dji.sample.common.constant.CommonConstant;
import com.dji.sample.common.model.CustomClaim;
import com.dji.sample.common.model.KeyCustomClaim;
import com.dji.sample.common.model.ResponseResult;
import com.dji.sample.common.model.SocketMsg;
import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.component.websocket.model.BizCodeEnum;
import com.dji.sample.component.websocket.model.CustomWebSocketMessage;
import com.dji.sample.component.websocket.service.ISendMessageService;
import com.dji.sample.component.websocket.service.impl.WebSocketManageServiceImpl;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.UserDTO;
import com.dji.sample.manage.model.enums.UserTypeEnum;
import com.dji.sample.manage.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;

/**
 * @author yjt
 * @date 2022-09-28
 * @description:
 */
@RestController
@RequestMapping("/send")
public class SendMsgController {

    @Autowired
    private RedisOpsUtils redisOps;

    @Autowired
    IUserService userService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    ISendMessageService iSendMessageService;

//    @GetMapping("/call/msg")
//    public ResponseResult<?> sendSocketMsg(@RequestParam(value = "deviceSn") String deviceSn, HttpServletRequest request, @RequestParam(value = "type") Integer type,@RequestParam(value = "key") String key) {
//        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
//        String keys = RedisConst.DEVICE_ONLINE_PREFIX + deviceSn;
//        Object o = redisOps.get(keys);
//        if (Objects.isNull(o)) {
//            return ResponseResult.error("当前设备未登录");
//        }
//        DeviceDTO device = (DeviceDTO) o;
//        //发送socket消息
//        UserDTO userDTO = userService.findUserByUserId(device.getUserId());
//        if (userDTO == null) {
//            return ResponseResult.error("用户未查询到");
//        }
//        KeyCustomClaim keyCustomClaim = new KeyCustomClaim();
//        BeanUtils.copyProperties(customClaim,keyCustomClaim);
//        keyCustomClaim.setKey(key);
//        String userTypeKey = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userDTO.getUserType()).getDesc();
//        LinkedHashMap<Object,Object> linkedHashMap = (LinkedHashMap<Object, Object>) redisTemplate.opsForHash().entries(userTypeKey);
//        ListIterator<Map.Entry<Object,Object>> i=new ArrayList<Map.Entry<Object,Object>>(linkedHashMap.entrySet()).listIterator(linkedHashMap.size());
//        String msg = type == 1 ? BizCodeEnum.CONVERSATION.getCode() : BizCodeEnum.DISCONNECT.getCode();
//        boolean bool = true;
//        while(i.hasPrevious() && bool) {
//            Map.Entry<Object, Object> entry=i.previous();
//            if(entry.getValue().equals(device.getUserId())){
//                iSendMessageService.sendMessage(WebSocketManageServiceImpl.SESSIONS.get(entry.getKey()), CustomWebSocketMessage.<CustomClaim>builder()
//                        .timestamp(System.currentTimeMillis())
//                        .bizCode(msg)
//                        .data(keyCustomClaim)
//                        .build());
//                bool=false;
//            }
//        }
//        if (bool) {
//            //集群模式 广播消息
//            if(mode.equals(CommonConstant.STAND_ALONE)){
//                return ResponseResult.error("未找到通话用户");
//            }
//
//        }
//        return ResponseResult.success("通话连通中...");
//    }

    @GetMapping("/call/msg")
    public ResponseResult<?> sendSocketMsg(@RequestParam(value = "deviceSn") String deviceSn, HttpServletRequest request, @RequestParam(value = "type") Integer type,@RequestParam(value = "key") String key) {
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        String keys = RedisConst.DEVICE_ONLINE_PREFIX + deviceSn;
        Object o = redisOps.get(keys);
        if (Objects.isNull(o)) {
            return ResponseResult.error("当前设备未登录");
        }
        DeviceDTO device = (DeviceDTO) o;
        //发送socket消息
        UserDTO userDTO = userService.findUserByUserId(device.getUserId());
        if (userDTO == null) {
            return ResponseResult.error("用户未查询到");
        }
        KeyCustomClaim keyCustomClaim = new KeyCustomClaim();
        BeanUtils.copyProperties(customClaim,keyCustomClaim);
        keyCustomClaim.setKey(key);
        String userTypeKey = CommonConstant.REDIS_USER_SESSION_KEY+device.getUserId();
        if(Boolean.FALSE.equals(redisTemplate.hasKey(userTypeKey))){
            return ResponseResult.error("未查询到在线用户");
        }
        Object val = redisTemplate.opsForValue().get(userTypeKey);
        String msg = type == 1 ? BizCodeEnum.CONVERSATION.getCode() : BizCodeEnum.DISCONNECT.getCode();
        iSendMessageService.sendMessage(WebSocketManageServiceImpl.SESSIONS.get(String.valueOf(val)), CustomWebSocketMessage.<CustomClaim>builder()
                .timestamp(System.currentTimeMillis())
                .bizCode(msg)
                .data(keyCustomClaim)
                .build(),device.getUserId(),String.valueOf(val));
        return ResponseResult.success("通话连通中...");
    }

    @GetMapping("/call/msg/byUserId")
    public ResponseResult<?> sendSocketMsgUserId(@RequestParam(value = "userId") String userId, HttpServletRequest request, @RequestParam(value = "type") Integer type,@RequestParam(value = "key") String key) {
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        UserDTO userDTO = userService.findUserByUserId(userId);
        if (userDTO == null) {
            return ResponseResult.error("用户未查询到");
        }
        KeyCustomClaim keyCustomClaim = new KeyCustomClaim();
        BeanUtils.copyProperties(customClaim,keyCustomClaim);
        keyCustomClaim.setKey(key);
        String userTypeKey = CommonConstant.REDIS_USER_SESSION_KEY+userDTO.getUserId();
        if(Boolean.FALSE.equals(redisTemplate.hasKey(userTypeKey))){
            return ResponseResult.error("未查询到在线用户");
        }
        Object val = redisTemplate.opsForValue().get(userTypeKey);
        String msg = type == 1 ? BizCodeEnum.CONVERSATION.getCode() : BizCodeEnum.DISCONNECT.getCode();
        iSendMessageService.sendMessage(WebSocketManageServiceImpl.SESSIONS.get(String.valueOf(val)), CustomWebSocketMessage.<CustomClaim>builder()
                .timestamp(System.currentTimeMillis())
                .bizCode(msg)
                .data(keyCustomClaim)
                .build(),userDTO.getUserId(),String.valueOf(val));
        return ResponseResult.success("通话连通中...");
    }

    @GetMapping("/call/msg/test")
    public ResponseResult<?> sendAll(){
        String userTypeKey = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(2).getDesc();
        LinkedHashMap<Object,Object> linkedHashMap = (LinkedHashMap<Object, Object>) redisTemplate.opsForHash().entries(userTypeKey);
        ListIterator<Map.Entry<Object,Object>> i=new ArrayList<Map.Entry<Object,Object>>(linkedHashMap.entrySet()).listIterator(linkedHashMap.size());
        String msg = BizCodeEnum.DISCONNECT.getCode();
        boolean bool = true;
        while(i.hasPrevious()) {
            Map.Entry<Object, Object> entry=i.previous();
            System.out.println(entry.getKey()+":"+entry.getValue());
            iSendMessageService.sendMessage(WebSocketManageServiceImpl.SESSIONS.get(entry.getKey()), CustomWebSocketMessage.<CustomClaim>builder()
                    .timestamp(System.currentTimeMillis())
                    .bizCode(msg)
                    .data(new CustomClaim())
                    .build());
        }
        if (bool) {
            return ResponseResult.error("未找到通话用户");
        }
        return ResponseResult.success();
    }

}


